import pygame
from pygame.sprite import Sprite

class Ship(Sprite):
    """
        管理飞船的类
        通过将游戏元素视为矩形，Pygame能够更快地判断出它们是否发生了碰撞。
        这种做法的效果通常很好，游戏玩家几乎注意不到我们处理的并不是游戏元素的实际形状。
        在这个类中，我们将把飞船和屏幕作为矩形进行处理。
    """

    # 参数：引用self和指向当前AlienInvasion实例的引用
    # 这让Ship能够访问AlienInvasion中定义的所有游戏资源。
    def __init__(self, ai_game):
        # 初始化飞船并设置其位置
        super().__init__()
        # 将屏幕赋给了Ship的一个属性，以便在这个类的所有方法中轻松访问。
        self.screen = ai_game.screen
        # 给Ship类添加属性settings，以便能够在update()中使用它
        self.settings = ai_game.settings

        # 使用方法get_rect()访问屏幕的属性rect（矩形），
        # 并将其赋给了self.screen_rect，这让我们能够将飞船放到屏幕的正确位置。
        self.screen_rect = ai_game.screen.get_rect()

        # 加载飞船图像，并获取其外接矩形
        self.image = pygame.image.load('images/ship.bmp')
        # 加载图像后，使用get_rect()获取相应surface的属性rect，
        # 以便后面能够使用它来指定飞船的位置。
        self.rect = self.image.get_rect()

        """
        要让游戏元素居中，可设置相应rect对象的属性center、centerx或centery；
        要让游戏元素与屏幕边缘对齐，可使用属性top、bottom、left或right。
        除此之外，还有一些组合属性，如midbottom、midtop、midleft和midright。
        """
        # 对于每艘新飞船，都将其放在屏幕底部的正中央
        self.rect.midbottom = self.screen_rect.midbottom
        # 在Pygame中，原点(0, 0)位于屏幕左上角，向右下方移动时，坐标值将增大。
        # 这些坐标对应的是游戏窗口，而不是物理屏幕。

        # 为准确存储飞船的位置，定义一个可存储小数值的新属性self.x
        # 使用函数float()将self.rect.x的值转换为小数，并将结果赋给self.x
        self.x = float(self.rect.x)

        # 在方法__init__()中，添加属性self.moving_right，并将其初始值设置为False
        self.moving_right = False
        self.moving_left = False



    def blitme(self):
        # 在指定的位置绘制飞船
        self.screen.blit(self.image, self.rect)

    # 添加方法update()
    def update(self):
        # 根据移动标志调整飞船位置(为True时)
        # 在update()中调整飞船的位置时，将self.x的值增减settings.ship_speed的值
        # self.rect.right返回飞船外接矩形右边缘的x坐标，如果这个值小于self.screen_rect.right的值，就说明飞船未触及屏幕右边缘
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.x += self.settings.ship_speed
        # 如果rect左边缘的x坐标大于零，就说明飞船未触及屏幕左边缘
        if self.moving_left and self.rect.left > 0:
            self.x -= self.settings.ship_speed
        """
        添加一个if代码块而不是elif代码块，这样如果玩家同时按下了左右箭头键，
        将先增加再减少飞船的rect.x值，即飞船的位置保持不变。
        如果使用一个elif代码块来处理向左移动的情况，右箭头键将始终处于优先地位。
        从向左移动切换到向右移动时，玩家可能同时按住左右箭头键，此时前面的做法让移动更准确。
        """
        # 根据self.x更新rect对象，self.rect.x只存储self.x的整数部分，但对显示飞船而言，这问题不大。
        self.rect.x = self.x

    def center_ship(self):
        # 让飞船在屏幕底端居中后，重置用于跟踪飞船确切位置的属性self.x
        self.rect.midbottom = self.screen_rect.midbottom
        self.x = float(self.rect.x)